#include <iostream>
#include <string>
#include <vector>

static bool _checkPath(const char *start, int len) {
  if (!start || len <= 0) return false;
  if (start[len-1] == '.') {
    do {
      if (len == 1) break;
      if (len == 2 && start[0] == '.') break;
      return false;
    } while (0);
  }
  static const char *sps = "\\/<>:\"|?*";
  char ch;
  for (int i = 0; i < len; ++i) {
    ch = start[i];
    for (int j = strlen(sps) - 1; j >= 0; --j)
      if (sps[j] == ch)
        return false;
  }
  return true;
}
static bool isPathInvalid(const char *path, int len) {
  if (!path || len <= 0) return true;

	bool found = false;
	int bpos = 0;
	for (int i = 0; i < len; ++i) {
		if (path[i] != '\\'
        && path[i] != '/') continue;

    if (!found) {
      found = true;
      bpos = i;
      if (bpos == len - 1)
        return false;
      continue;
    }
    
    {
      if ((i < len - 1)
          && (path[i + 1] == '\\' || path[i + 1] == '/'))
        continue;

      if (!_checkPath(&path[bpos+1], i - bpos - 1))
        return true;

      if (i+1 == len)
        return false;

      bpos = i;
      found = true;
    }
	}

  if (!found) {
    if (len != 2) return false;
    if (path[1] != ':') return false;
    if (path[0] >= 'a' && path[0] <= 'z') return true;
    if (path[0] >= 'A' && path[0] <= 'Z') return true;
    return false;
  }

  if (bpos < len - 1) {
    return !_checkPath(&path[bpos+1], len - 1 - bpos);
  }

  return false;
}

#include <windows.h>

static struct Color {
  Color() {}
  static inline std::ostream& Red(std::ostream &s) {
    HANDLE hStdout = ::GetStdHandle(STD_OUTPUT_HANDLE); 
    ::SetConsoleTextAttribute(hStdout, 
        FOREGROUND_RED|FOREGROUND_INTENSITY);
    return s;
  }
  static inline std::ostream& Green(std::ostream &s) {
    HANDLE hStdout = ::GetStdHandle(STD_OUTPUT_HANDLE); 
    ::SetConsoleTextAttribute(hStdout, 
        FOREGROUND_GREEN|FOREGROUND_INTENSITY);
    return s;
  }
  static inline std::ostream& Default(std::ostream &s) {
    HANDLE hStdout = ::GetStdHandle(STD_OUTPUT_HANDLE); 
    ::SetConsoleTextAttribute(hStdout, 
        7|FOREGROUND_INTENSITY);
    return s;
  }
} __color;

int main(int argc, char *argv[]) {
  auto log = [](const std::string &path) {
    if (path.empty()) {
      std::cout << std::endl;
      return;
    }
    isPathInvalid(path.c_str(), path.length())
        ? (std::cout << Color::Red << "FALSE")
        : (std::cout << Color::Green << "TRUE");
    std::cout << Color::Default << "\t" << path
      << std::endl;
  };

  std::vector<std::string> paths = {
    "c:\\a",
    "c:\\a\\",
    "c:\\\\a",
    "c:\\\\\\a",
    "c:\\.\\a",
    "c:\\..\\a",
    "c:\\...\\a",
    "c:\\.a",
    "c:\\..a",
    "c:\\...a",
    "c:\\a.",
    "c:\\a..",
    "c:\\a...",
    "",
    "c:\\a\\",
    "c:\\a\\\\",
    "c:\\\\a\\",
    "c:\\\\\\a\\",
    "c:\\.\\a\\",
    "c:\\..\\a\\",
    "c:\\...\\a\\",
    "c:\\.a\\",
    "c:\\..a\\",
    "c:\\...a\\",
    "c:\\a.\\",
    "c:\\a..\\",
    "c:\\a...\\",
    "",
    "c:/a",
    "c:/a/",
    "c:/a//",
    "c://a/",
    "c:///a/",
    "c:/./a/",
    "c:/../a/",
    "c:/.../a/",
    "c:/.a/",
    "c:/..a/",
    "c:/...a/",
    "c:/a./",
    "c:/a../",
    "c:/a.../",
    "",
    "c:/a/b/c",
    "",
    "c:/a/\\/c",
    "c:/a///c",
    "c:/a/</c",
    "c:/a/>/c",
    "c:/a/:/c",
    "c:/a/\"/c",
    "c:/a/|/c",
    "c:/a/?/c",
    "c:/a/*/c",
    "c:/a/!/c",
    "c:/a/@/c",
    "c:/a/#/c",
    "c:/a/$/c",
    "c:/a/^/c",
    "c:/a/&/c",
    "c:/a/(/c",
    "c:/a/)/c",
    "c:/a/-/c",
    "c:/a/+/c",
    "c:/a/=/c",
    "",
    "c:/a/b\\/c",
    "c:/a/b//c",
    "c:/a/b</c",
    "c:/a/b>/c",
    "c:/a/b:/c",
    "c:/a/b\"/c",
    "c:/a/b|/c",
    "c:/a/b?/c",
    "c:/a/b*/c",
    "c:/a/b!/c",
    "c:/a/b@/c",
    "c:/a/b#/c",
    "c:/a/b$/c",
    "c:/a/b^/c",
    "c:/a/b&/c",
    "c:/a/b(/c",
    "c:/a/b)/c",
    "c:/a/b-/c",
    "c:/a/b+/c",
    "c:/a/b=/c",
    "",
    "c:/a/\\b/c",
    "c:/a//b/c",
    "c:/a/<b/c",
    "c:/a/>b/c",
    "c:/a/:b/c",
    "c:/a/\"b/c",
    "c:/a/|b/c",
    "c:/a/?b/c",
    "c:/a/*b/c",
    "c:/a/!b/c",
    "c:/a/@b/c",
    "c:/a/#b/c",
    "c:/a/$b/c",
    "c:/a/^b/c",
    "c:/a/&b/c",
    "c:/a/(b/c",
    "c:/a/)b/c",
    "c:/a/-b/c",
    "c:/a/+b/c",
    "c:/a/=b/c",
    "",
    "c:/a/b\\b/c",
    "c:/a/b/b/c",
    "c:/a/b<b/c",
    "c:/a/b>b/c",
    "c:/a/b:b/c",
    "c:/a/b\"b/c",
    "c:/a/b|b/c",
    "c:/a/b?b/c",
    "c:/a/b*b/c",
    "c:/a/b!b/c",
    "c:/a/b@b/c",
    "c:/a/b#b/c",
    "c:/a/b$b/c",
    "c:/a/b^b/c",
    "c:/a/b&b/c",
    "c:/a/b(b/c",
    "c:/a/b)b/c",
    "c:/a/b-b/c",
    "c:/a/b+b/c",
    "c:/a/b=b/c",
    "",
    "C:\\Program Files (x86)\\Huorong",
  };

  for (auto &v : paths)
    log(v);

  return 0;
}